/*
 * Copyright (c) 2016- 2020 qolome.com Inc. All Rights Reserved.
 * ProjectName: qolome-knowledge
 * FileName: QolomeProxy.java
 * Author: jiangfeng@qolome.com
 * Date: 2020/3/3 下午1:13
 * LastModified: 2020/03/03 12:42:03
 */

package com.qolome.knowledge.design.pattern.proxy.demo.proxy;

import com.qolome.knowledge.design.pattern.proxy.demo.classes.ClassBuilder;

import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;

/**
 * @author Qolome
 * @version V1.0
 * @Description 代理类
 * @date 2020年 03月03日 12:40:54
 */
public class QolomeProxy {
    public static final String Ln = "\r\n";
    public static final String END = ";" + Ln;
    public static final String IMPORT = "import ";

    /**
     * 代理实现
     *
     * @param classLoader
     * @param interfaces
     * @param h
     * @return
     */
    public static Object newProxyInstance(QolomeClassLoader classLoader,
                                          Class<?>[] interfaces,
                                          QolomeInvocationHandler h) {

        try {
            String src = generateSrc(interfaces);

            System.out.println(src);

            String filePath = QolomeProxy.class.getResource("").getPath();
            System.out.println(src);
            File file = new File(filePath + "$Proxy0.java");
            FileWriter fw = new FileWriter(file);
            fw.write(src);
            fw.flush();
            fw.close();

            //3、把生成的.java文件编译成.class文件
            JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

            StandardJavaFileManager manage = compiler.getStandardFileManager(null,null,null);
            Iterable iterable = manage.getJavaFileObjects(file);


            JavaCompiler.CompilationTask task = compiler.getTask(null,manage,null,null,null,iterable);
            task.call();
            manage.close();

            //4、编译生成的.class文件加载到JVM中来
            Class proxyClass =  classLoader.findClass("$Proxy0");
            Constructor c = proxyClass.getConstructor(QolomeInvocationHandler.class);
            file.delete();


            //5、返回字节码重组以后的新的代理对象
            return c.newInstance(h);


        } catch (Exception e) {
            e.printStackTrace();
        }
        // 1.动态生成源码 .java
        // 2. Java文件输出磁盘,另存为文件$Proxy0.java
        // 2.编译文件   $Proxy0.java->  $Proxy0.class
        // 4.加载到JVM中
        // 5.返回新的代理对象
        return null;
    }

    /**
     * 生辰源文件
     *
     * @param interfaces
     * @return
     */
    private static String generateSrc(Class<?>[] interfaces) {

        return new ClassBuilder()
                .packageName(QolomeProxy.class.getPackage().toString())
                .className("$Proxy0")
                .addImport(interfaces[0].getName())
                .addImport("java.lang.reflect.*")
                .addImplement(interfaces[0].getSimpleName())
                .field("QolomeInvocationHandler h")
                .method("public $Proxy0", "QolomeInvocationHandler h", "this.h = h;")
                .methods(interfaces[0].getMethods(), interfaces[0].getSimpleName())
                .builder();

    }
}